package com.neptune.imapp.ui.compose.screen.mainPage

import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.neptune.imapp.repository.entity.User
import com.neptune.imapp.repository.service.UserService
import com.neptune.imapp.repository.vo.Apply
import com.neptune.imapp.repository.vo.ApplyForMain
import com.neptune.imapp.ui.compose.screen.BasicViewModel
import com.neptune.imapp.ui.compose.screen.SocketClient
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import java.net.URI
import javax.inject.Inject

@HiltViewModel
class MainViewModel @Inject constructor(
    private val userService: UserService
) : ViewModel() {
    sealed class State {
        object Loading : State()
        data class Data(
            val user: User,
            val applies: List<Apply>,
            val mainApplies: List<ApplyForMain>
        ) : State()
    }

    val state = MutableStateFlow<State>(State.Loading)
    private lateinit var socketClient: SocketClient

    @Inject
    lateinit var basicViewModel: BasicViewModel
    val searchInfo = mutableStateOf("")

    val isChat = mutableStateOf(false)
    var username = mutableStateOf("")

    init {
        viewModelScope.launch {
            try {
                val selfInfo = async { userService.getSelfInfo(16) }
                val resume = async { userService.getSelfResume(16) }
                val applyList = async { userService.getSelfApply(16) }
                val mainApplies = async { userService.getMainApply(0f, 0f, "", "", 0, "", "") }
                state.value = State.Data(
                    User(
                        selfInfo = selfInfo.await().data,
                        resume = resume.await().data
                    ), applies = applyList.await().data,
                    mainApplies = mainApplies.await().data
                )
                socketClient = SocketClient(
                    URI("ws://192.168.1.3:8085/connect/" + basicViewModel.telephone)
                )
                applies.value = ApplyListState.Data(mainApplies.await().data)
                socketClient.connect()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    val applies = MutableStateFlow<ApplyListState>(ApplyListState.Loading)

    sealed class ApplyListState {
        object Loading : ApplyListState()
        data class Data(val apply: List<ApplyForMain>) : ApplyListState()
    }

    fun applyFilter(
        minSalary: Float,
        maxSalary: Float,
        address: String,
        education: String,
        time: Int,
        vacation: String,
        name: String
    ) {
        viewModelScope.launch {
            try {
                applies.value = ApplyListState.Loading
                val result = userService.getMainApply(
                    minSalary = minSalary,
                    maxSalary = maxSalary,
                    address = address,
                    education = education,
                    time = time,
                    vacation = vacation,
                    name = name
                )
                applies.value = ApplyListState.Data(result.data)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

}